﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using LevelEditor.Classes;

namespace LevelEditor
{
    public partial class LevelEditor : Form
    {
        public int MAP_WIDTH = 4096;
        public int MAP_HEIGHT = 2000;
        private const float viewWorldScalingx = 0;
        private const float viewWorldScalingy = 0;
        public int currentLevel = 1;
        public List<CustomObject> objects;
        public List<CustomObject> objectsOnScreen;
        public XmlHandler xmlHandler;
        public TextHandler texthandler;
        private OpenFileDialog folderDialog;
        private SaveFileDialog saveDialog;
        private CustomObject selectedObject;
        public PictureBox pictureBox1;
        private System.Drawing.Point globalOffset;
        private Pen purplePen = new Pen(System.Drawing.Color.Purple);
        private int mouseDownCounter = 100;

        public LevelEditor()
        {
            InitializeComponent();
            this.AllowDrop = true;
            this.Load += editpane_Load;
            objects = new List<CustomObject>();
            objectsOnScreen = new List<CustomObject>();
            xmlHandler = new XmlHandler(this);
            texthandler = new TextHandler(this);
            xmlHandler.currentDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + LocationManager.currDirectoryX86;
            texthandler.load();
        }
        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void runToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + LocationManager.racePlatformer_LOC, "");
        }

        private void loadLevelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            folderDialog = new OpenFileDialog();
            //folderDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            folderDialog.Filter = "XML Files (*.xml)|*.xml";
            folderDialog.FileOk += new CancelEventHandler(folderDialog_FileOk);
            folderDialog.ShowDialog();
            //program will continue after cancel or open has been clicked
        }

        public void folderDialog_FileOk(object sender, CancelEventArgs e)
        {
            String safefilename = folderDialog.SafeFileName;
            String subS = safefilename.Substring(5, 1);
            currentLevel = (int)Convert.ToDouble(subS);
            currentLVL.Text = "Working in level : " + currentLevel;
            xmlHandler.filename = folderDialog.FileName;
            xmlHandler.load(folderDialog.FileName);
            xmlHandler.newLevel = false;
        }

        private void saveLevelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (xmlHandler.newLevel)
            {
                saveDialog = new SaveFileDialog();
                saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                saveDialog.FileName = "level" + currentLevel + ".xml";
                saveDialog.FileOk += new CancelEventHandler(saveDialog_FileOk);
                saveDialog.ShowDialog();
                //program will continue after cancel or open has been clicked
            }
            else
            {
                xmlHandler.save(xmlHandler.filename);
                MessageBox.Show("File has been saved at the original location!");
            }
        }

        void saveDialog_FileOk(object sender, CancelEventArgs e)
        {
            xmlHandler.save(saveDialog.FileName);
        }

        private void createNewLevelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewLevel nl = new NewLevel(this);
            nl.Visible = true;
        }

        private void setProperties()
        {

        }
        private void LevelEditor_Load(object sender, EventArgs e)
        {
        }
        // This example creates a PictureBox control on the form and draws to it.
        // This example assumes that the Form_Load event handling method is
        // connected to the Load event of the form.
        // MUST ADD HANDLER TOT HE PICTURE BOX, NOT THE PANEL FFS.
        private void editpane_Load(object sender, System.EventArgs e)
        {
            pictureBox1 = new PictureBox();
            pictureBox1.Width = MAP_WIDTH;
            pictureBox1.Height = MAP_HEIGHT;
            pictureBox1.MouseUp += new MouseEventHandler(pictureBox_MouseUp);
            pictureBox1.MouseDown += new MouseEventHandler(pictureBox_MouseDown);
            // Dock the PictureBox to the form and set its background to white.
            //pictureBox1.Dock = DockStyle.Fill;
            pictureBox1.BackColor = System.Drawing.Color.LightBlue;
            // Connect the Paint event of the PictureBox to the event handling method.
            pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
            // Add the PictureBox control to the Form.
            editPanel.Controls.Add(pictureBox1);
            calcOffset();
            Console.WriteLine("[editpane_Load] GLOBAL OFFSET : " + globalOffset);
        }

        private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            // Create a local version of the graphics object for the PictureBox.
            Graphics g = e.Graphics;

            foreach (CustomObject cu in objectsOnScreen)
            {
                g.DrawImage(cu.image, new System.Drawing.Rectangle((int)cu.Position.X, (int)cu.Position.Y, (int)cu.size.X, (int)cu.size.Y));
                g.DrawRectangle(purplePen, (int)cu.Position.X, (int)cu.Position.Y, (int)cu.size.X, (int)cu.size.Y);
            }
            //pictureBox1.Invalidate();
        }

        private void createNewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewObject nPanel = new NewObject(this);
            nPanel.Visible = true;
        }
        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (selectedObject != null)
                {
                    selectedObject.Position = new Vector2(((e.X + globalOffset.X) - (selectedObject.size.X / 2)), (e.Y + globalOffset.Y) - (selectedObject.size.Y / 2));
                    // selectedObject = null;
                    pictureBox1.Invalidate();
                }
            }
        }

        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left || e.Button == MouseButtons.Right)
            {
                foreach (CustomObject cu in objectsOnScreen)
                {
                    if (((e.X + globalOffset.X) >= cu.Position.X &&
                        (e.X + globalOffset.X) <= (cu.Position.X + cu.size.X)
                        && ((e.Y + globalOffset.Y) >= cu.Position.Y &&
                        (e.Y + globalOffset.Y) <= (cu.Position.Y + cu.size.Y))))
                    {
                        selectedObject = cu;
                        selectedobjectlabel.Text = selectedObject.name;
                        fillProperties(selectedObject);
                        pictureBox1.Invalidate();
                    }
                }
            }
        }
        private void fillProperties(CustomObject selectedObject)
        {
            //empty temp!
            emptyValues();

            objectHeightBox2.Text = (String)selectedObject.size.Y.ToString();
            objectMassBox.Text = (String)selectedObject.mass.ToString();
            objectnameTextBox.Text = (String)selectedObject.name;
            objectRotationBox.Text = (String)selectedObject.rotation.ToString();
            objectWidthBox.Text = (String)selectedObject.size.X.ToString();
            objectXPos.Text = (String)selectedObject.Position.X.ToString();
            objectYPos.Text = (String)selectedObject.Position.Y.ToString();
            bodyTypeBox.SelectedText = (String)selectedObject.bodyType;
            //typeBox.SelectedText = (String)selectedObject.
        }
        private void emptyValues()
        {
            objectHeightBox2.Text = "";
            objectMassBox.Text = "";
            objectnameTextBox.Text = "";
            objectRotationBox.Text = "";
            objectWidthBox.Text = "";
            objectXPos.Text = "";
            bodyTypeBox.SelectedIndex = 0;
            bodyTypeBox.SelectedValue = "";
            bodyTypeBox.SelectedItem = null;
            objectYPos.Text = "";
            bodyTypeBox.SelectedText = "";
            bodyTypeBox.SelectedItem = null;
        }
        private void editPanel_Paint(object sender, PaintEventArgs e)
        {

        }

        private void recalculateOffset(object sender, DragEventArgs e)
        {
            calcOffset();
        }

        private void recalculateOffset(object sender, EventArgs e)
        {
            calcOffset();
        }
        private void calcOffset()
        {
            globalOffset = this.PointToClient(this.Location);
            globalOffset.X += (pictureBox1.Location.X);
            //globalOffset.Y += (pictureBox1.Location.Y);
            globalOffset.Y += (28);
        }

        private void label11_Click(object sender, EventArgs e)
        {

        }

        private void editProperties_Click(object sender, EventArgs e)
        {
            selectedObject.bodyType = bodyTypeBox.Text;
            selectedObject.mass = (float)Convert.ToDouble(objectMassBox.Text);
            selectedObject.rotation = (float)Convert.ToDouble(objectRotationBox.Text);
            selectedObject.size.X = (float)Convert.ToDouble(objectWidthBox.Text);
            selectedObject.size.Y = (float)Convert.ToDouble(objectHeightBox2.Text);
            selectedObject.name = objectnameTextBox.Text;
            MessageBox.Show("changed the properties of object with name " + selectedObject.name);
        }

        private void groundBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            foreach (CustomObject cu in objects)
            {
                if (cu.name.Equals(groundBox.SelectedItem.ToString()))
                {
                    CustomObject tempObject = copyObject(cu);
                    objectsOnScreen.Add(tempObject);
                    pictureBox1.Invalidate();
                    groundBox.SelectedIndex = 0;
                }
            }
        }

        private void normalBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            foreach (CustomObject cu in objects)
            {
                if (cu.name.Equals(normalBox.SelectedItem.ToString()))
                {
                    CustomObject tempObject = copyObject(cu);
                    objectsOnScreen.Add(tempObject);
                    pictureBox1.Invalidate();
                    normalBox.SelectedIndex = 0;
                }
            }
        }

        private void itemBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            foreach (CustomObject cu in objects)
            {
                if (cu.name.Equals(itemBox.SelectedItem.ToString()))
                {
                    CustomObject tempObject = copyObject(cu);
                    objectsOnScreen.Add(tempObject);
                    pictureBox1.Invalidate();
                    itemBox.SelectedIndex = 0;
                }
            }
        }

        private void deleteSelectedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            objectsOnScreen.Remove(selectedObject);
            selectedObject = null;
            pictureBox1.Invalidate();
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void internalScreenResolutionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ScreenSettings inp = new ScreenSettings(this, MAP_WIDTH, MAP_HEIGHT);
            inp.Visible = true;
            inp.Show();
        }

        private CustomObject copyObject(CustomObject from)
        {
            CustomObject temp = new CustomObject();
            temp.name = from.name;
            temp.image = from.image;
            temp.bodyType = from.bodyType;
            temp.imageURL = from.imageURL;
            temp.currentType = from.currentType;
            temp.mass = 0;
            temp.Position = new Vector2(0, 0);
            temp.relativeImageUrl = from.relativeImageUrl;
            temp.rotation = 0;
            temp.size = from.size;
            return temp;
        }
        private CustomObject copyPaste(CustomObject from)
        {
            CustomObject temp = new CustomObject();
            temp.name = from.name;
            temp.image = from.image;
            temp.bodyType = from.bodyType;
            temp.imageURL = from.imageURL;
            temp.currentType = from.currentType;
            temp.mass = from.mass;
            temp.Position = new Vector2(from.Position.X+from.size.X, from.Position.Y);
            temp.relativeImageUrl = from.relativeImageUrl;
            temp.rotation = from.rotation;
            temp.size = from.size;
            return temp;
        }

        private void CopyObjectButton_Click(object sender, EventArgs e)
        {
            if (selectedObject != null)
            {
                CustomObject tempObject = copyPaste(selectedObject);
                objectsOnScreen.Add(tempObject);
                pictureBox1.Invalidate();
            }
        }

        private void copySelectedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (selectedObject != null)
            {
                CustomObject tempObject = copyPaste(selectedObject);
                objectsOnScreen.Add(tempObject);
                pictureBox1.Invalidate();
            }
        }

        private void deleteButton2_Click(object sender, EventArgs e)
        {
            objectsOnScreen.Remove(selectedObject);
            selectedObject = null;
            pictureBox1.Invalidate();
        }

        private void changeAmountOfPlayerSpawningToolStripMenuItem_Click(object sender, EventArgs e)
        {
            amountofplayerSpawningForm ampsf = new amountofplayerSpawningForm(this);
            ampsf.Visible = true;
        }
    }
}
